﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Linq;

namespace Gmantis.Controls.Chart
{
    public class Renderer2D : BaseRenderer, IView2DRenderer, IRenderer
    {
        // Fields
        private Rect _rect = new Rect();
        private static double cosPi6 = Math.Cos(0.52359877559829882);
        private static object DefSymbol = new DotSymbol();
        private static double sinPi6 = Math.Sin(0.52359877559829882);
        private Brush TransparentBrush = new SolidColorBrush(Colors.Transparent);
        internal string[] ValidAuxAxes;

        // Methods
        public Renderer2D()
        {
            base.Symbol = DefSymbol;
        }

        internal override void AdjustAxisInternal(IAxis ax, double delta)
        {
            ax.Visible = true;
            switch (ax.AxisType)
            {
                case AxisType.X:
                    {
                        if (this._rect.Width <= 0.0)
                        {
                            break;
                        }
                        ValueLabels labels = ValueLabels.Create(ax.Min, ax.Max, ax);
                        if ((base.ItemNames == null) || base.Inverted)
                        {
                            ax.AddLabels(labels.Vals, labels.Lbls);
                            return;
                        }
                        ax.AddLabels(labels.Vals, base.ItemNames);
                        return;
                    }
                case AxisType.Y:
                    {
                        if (this._rect.Height <= 0.0)
                        {
                            break;
                        }
                        ValueLabels labels2 = ValueLabels.Create(ax.Min, ax.Max, ax);
                        if ((base.ItemNames == null) || !base.Inverted)
                        {
                            ax.AddLabels(labels2.Vals, labels2.Lbls);
                            break;
                        }
                        ax.AddLabels(labels2.Vals, base.ItemNames);
                        return;
                    }
                default:
                    return;
            }
        }

        UIElement[] IView2DRenderer.Generate()
        {
            int nser = this._dataInfo.nser;
            int npts = this._dataInfo.npts;
            if ((nser == 0) || (npts == 0))
            {
                return null;
            }
            List<UIElement> objects = new List<UIElement>();
            Rect dataBounds = this.CoordConverter.DataBounds;
            bool isStacked = base.IsStacked;
            StackedSum sum = null;
            StackedSum sum2 = null;
            StackedSum sum3 = null;
            int nsg = 1;
            if (isStacked)
            {
                nsg = base.NStackGroups();
                sum = new StackedSum(nsg);
                sum2 = new StackedSum(nsg);
                sum3 = new StackedSum(nsg);
            }
            double num4 = this.GetClusterWidth() * this._dataInfo.DeltaX;
            IPlotElement defel = null;
            if (base.Symbol is PlotElement)
            {
                defel = ((PlotElement)base.Symbol).Clone() as IPlotElement;
            }
            bool defval = (defel != null) ? defel.IsClustered : false;
            bool inverted = base.Inverted;
            int num5 = 0;
            int[] numArray = null;
            int[] numArray2 = null;
            if (isStacked)
            {
                num5 = base.NStackGroups();
            }
            else
            {
                numArray = this.NClustered(defval);
                numArray2 = new int[numArray.Length];
                num5 = numArray[0];
            }
            double d = 0.0;
            double origin = 0.0;
            double seriesOverlap = 0.0;
            Chart visual = ((IRenderer)this).Visual as Chart;
            string xformat = null;
            string yformat = null;
            bool flag4 = false;
            bool flag5 = false;
            if (visual != null)
            {
                origin = BarColumnOptions.GetOrigin(visual);
                xformat = visual.View.AxisX.AnnoFormatInternal;
                yformat = visual.View.AxisY.AnnoFormatInternal;
                flag4 = !double.IsNaN(visual.View.AxisX.LogBase);
                flag5 = !double.IsNaN(visual.View.AxisY.LogBase);
                seriesOverlap = BarColumnOptions.GetSeriesOverlap(visual);
                if (seriesOverlap > 1.0)
                {
                    seriesOverlap = 1.0;
                }
                else if (seriesOverlap < -1.0)
                {
                    seriesOverlap = -1.0;
                }
            }
            int si = 0;
            int num10 = 0;
            while (si < nser)
            {
                IDataSeriesInfo ds = base.Series[si];
                int count = objects.Count;
                DataSeries item = (DataSeries)base.Series[si];
                item.Children.Clear();
                objects.Add(item);
                item.SetDefaultFormat(xformat, yformat);
                int stackGroup = 0;
                if (isStacked)
                {
                    stackGroup = BarColumnOptions.GetStackGroup(item);
                }
                if (item.SymbolShape == null)
                {
                    item.SymbolShape = base.StyleGen.Next();
                }
                ShapeStyle symbolShape = item.SymbolShape;
                bool? nullable = null;
                double[,] values = ds.GetValues();
                if (values != null)
                {
                    RenderMode renderMode = item.RenderMode;
                    if (IsFastMode(renderMode))
                    {
                        nullable = true;
                    }
                    int length = values.GetLength(1);
                    int num13 = values.GetLength(0);
                    RenderContext rc = new RenderContext(this, ds, length)
                    {
                        Bounds = this.CoordConverter.ViewBounds
                    };
                    Rect clipBounds = rc.ClipBounds;
                    clipBounds = new Rect(clipBounds.X - 1.0, clipBounds.Y - 1.0, clipBounds.Width + 2.0, clipBounds.Height + 2.0);
                    double naN = double.NaN;
                    if ((rc.OptimizationRadiusScope & OptimizationRadiusScope.Symbols) > ((OptimizationRadiusScope)0))
                    {
                        naN = rc.OptimizationRadius;
                    }
                    bool isClustered = defval;
                    bool flag7 = item.IsStacked;
                    int num65 = objects.Count;
                    int num15 = 0;
                    int num16 = length;
                    if (this._dataInfo.incX && !inverted)
                    {
                        Rect rect2 = this.CoordConverter.DataBounds2D;
                        for (int j = 0; j < length; j++)
                        {
                            double num18 = (num13 >= 2) ? values[1, j] : ((double)j);
                            if (num18 >= rect2.Left)
                            {
                                num15 = Math.Max(0, j - 2);
                                break;
                            }
                        }
                        for (int k = num15; k < length; k++)
                        {
                            double num20 = (num13 >= 2) ? values[1, k] : ((double)k);
                            if (num20 > rect2.Right)
                            {
                                num16 = k;
                                break;
                            }
                        }
                        num16 = Math.Min(length, num16 + 2);
                    }
                    Point point = new Point();
                    for (int i = num15; i < num16; i++)
                    {
                        double num22 = values[0, i];
                        double x = (num13 >= 2) ? values[1, i] : ((double)i);
                        double y = x;
                        Style style = null;
                        IPlotElement pe = null;
                        if (nullable != true)
                        {
                            if (base.ColorScheme == ColorScheme.Point)
                            {
                                symbolShape = base.StyleGen.GetStyle(i);
                            }
                            style = base.GetStyle(item, si, i);
                            pe = base.CreateElement(item.Symbol, style);
                            if (pe == null)
                            {
                                pe = PlotElement.SymbolFromMarker(item.SymbolMarker);
                                if ((pe != null) && (style != null))
                                {
                                    pe.Style = style;
                                }
                            }
                            if ((pe == null) && item.ChartType.HasValue)
                            {
                                ChartSubtype subtype = ChartTypes.GetSubtype(item.ChartType.ToString());
                                if (subtype != null)
                                {
                                    pe = base.CreateElement(subtype.Symbol, style);
                                }
                            }
                            else if (pe == null)
                            {
                                if (item.IsDefaultSymbol && (defel != null))
                                {
                                    pe = defel;
                                    pe.Style = style;
                                    defel = ((PlotElement)base.Symbol).Clone() as IPlotElement;
                                }
                            }
                            else
                            {
                                isClustered = pe.IsClustered;
                            }
                            if (pe == null)
                            {
                                isClustered = false;
                                if ((item.PointLabelTemplate != null) || (item.PointTooltipTemplate != null))
                                {
                                    DotSymbol symbol = new DotSymbol
                                    {
                                        Fill = this.TransparentBrush,
                                        Size = new Size(5.0, 5.0),
                                        Stroke = this.TransparentBrush
                                    };
                                    pe = symbol;
                                }
                                else
                                {
                                    nullable = true;
                                }
                            }
                            else
                            {
                                isClustered = pe.IsClustered;
                            }
                        }
                        bool flag8 = (flag4 && inverted) || (flag5 && !inverted);
                        if (!flag8)
                        {
                            if (nsg > 1)
                            {
                                if (flag7)
                                {
                                    x += ((-0.5 * num4) + ((0.5 * num4) / ((double)num5))) + ((stackGroup * num4) / ((double)num5));
                                }
                            }
                            else if (isClustered)
                            {
                                int clusterPlotAreaIndex = rc.ClusterPlotAreaIndex;
                                if (clusterPlotAreaIndex == 0)
                                {
                                    if (num5 > 1)
                                    {
                                        x += ((-0.5 * num4) + ((0.5 * num4) / ((double)num5))) + ((num10 * num4) / ((double)num5));
                                    }
                                }
                                else if (numArray[clusterPlotAreaIndex] > 1)
                                {
                                    x += ((-0.5 * num4) + ((0.5 * num4) / ((double)numArray[clusterPlotAreaIndex]))) + ((numArray2[clusterPlotAreaIndex] * num4) / ((double)numArray[clusterPlotAreaIndex]));
                                }
                            }
                        }
                        if (isStacked && flag7)
                        {
                            if (double.IsNaN(num22))
                            {
                                num22 = 0.0;
                            }
                            if (base.IsStacked100)
                            {
                                if (this._dataInfo.Stacked[stackGroup, x] != 0.0)
                                {
                                    num22 = ((num22 * 100.0) / this._dataInfo.Stacked[stackGroup, x]) + sum[stackGroup, x];
                                }
                            }
                            else
                            {
                                num22 += sum[stackGroup, x];
                            }
                        }
                        double num26 = x;
                        if (inverted)
                        {
                            double num27 = x;
                            x = num22;
                            num22 = num27;
                        }
                        double num28 = rc.ConvertX(x);
                        double num29 = rc.ConvertY(num22);
                        if (((isStacked && flag7) && (si > 0)) && ((inverted && !double.IsNaN(num29)) || (!inverted && !double.IsNaN(num28))))
                        {
                            rc.SetPrevious(sum[stackGroup, num26]);
                        }
                        if (nullable != true)
                        {
                            if (isClustered)
                            {
                                int num30 = num5;
                                if (rc.ClusterPlotAreaIndex > 0)
                                {
                                    num30 = numArray[rc.ClusterPlotAreaIndex];
                                }
                                if (num30 > 0)
                                {
                                    if (inverted)
                                    {
                                        d = Math.Abs((double)(this.CoordConverter.ConvertY((num4 / ((double)num30)) + num22) - this.CoordConverter.ConvertY(num22)));
                                    }
                                    else
                                    {
                                        d = Math.Abs((double)(this.CoordConverter.ConvertX((num4 / ((double)num30)) + x) - this.CoordConverter.ConvertX(x)));
                                    }
                                }
                            }
                            else if (inverted)
                            {
                                d = Math.Abs((double)(this.CoordConverter.ConvertY(num4 + num22) - this.CoordConverter.ConvertY(num22)));
                            }
                            else
                            {
                                d = Math.Abs((double)(this.CoordConverter.ConvertX(num4 + x) - this.CoordConverter.ConvertX(x)));
                            }
                            if (double.IsNaN(d))
                            {
                                d = inverted ? (base.SizeY * 20.0) : (base.SizeX * 20.0);
                            }
                        }
                        if (flag8)
                        {
                            double num31 = 0.0;
                            double num32 = d * num5;
                            if (nsg > 1)
                            {
                                if (flag7)
                                {
                                    num31 = ((-0.5 * num32) + ((0.5 * num32) / ((double)num5))) + ((stackGroup * num32) / ((double)num5));
                                }
                            }
                            else if ((num5 > 1) && isClustered)
                            {
                                num31 = ((-0.5 * num32) + ((0.5 * num32) / ((double)num5))) + ((num10 * num32) / ((double)num5));
                            }
                            if (num31 != 0.0)
                            {
                                if (inverted)
                                {
                                    num29 += num31;
                                }
                                else
                                {
                                    num28 += num31;
                                }
                            }
                        }
                        if (isStacked && flag7)
                        {
                            StackedSum sum4;
                            int num63;
                            double num64;
                            double num33 = values[0, i];
                            if (double.IsNaN(num33))
                            {
                                num33 = 0.0;
                            }
                            double num34 = (num33 >= 0.0) ? sum2[stackGroup, num26] : sum3[stackGroup, num26];
                            double num35 = (num33 >= 0.0) ? (sum2[stackGroup, num26] + num33) : (sum3[stackGroup, num26] + num33);
                            if (base.IsStacked100)
                            {
                                num34 = (num34 * 100.0) / this._dataInfo.Stacked[stackGroup, num26];
                                num35 = (num35 * 100.0) / this._dataInfo.Stacked[stackGroup, num26];
                            }
                            if (inverted)
                            {
                                double num36;
                                double num37;
                                double num38;
                                if (flag4)
                                {
                                    double minX = rc.GetMinX(this.CoordConverter.DataBounds2D);
                                    num36 = this.CoordConverter.ConvertX(Math.Max(num35, minX));
                                    num37 = this.CoordConverter.ConvertX(Math.Max(num34, minX));
                                }
                                else
                                {
                                    num36 = this.CoordConverter.ConvertX(num35);
                                    num37 = this.CoordConverter.ConvertX(num34);
                                }
                                if (flag5)
                                {
                                    num38 = base.SizeY * 20.0;
                                }
                                else
                                {
                                    num38 = Math.Abs((double)(this.CoordConverter.ConvertY(num4 / ((double)nsg)) - this.CoordConverter.ConvertY(0.0)));
                                }
                                double width = Math.Abs((double)(num37 - num36));
                                rc.Rect = new Rect(Math.Min(num36, num37), num29 - (0.5 * num38), width, num38);
                                sum[stackGroup, num26] = x;
                            }
                            else
                            {
                                double num41;
                                double num42;
                                double num43;
                                if (flag5)
                                {
                                    double minY = rc.GetMinY(this.CoordConverter.DataBounds2D);
                                    num41 = this.CoordConverter.ConvertY(Math.Max(num35, minY));
                                    num42 = this.CoordConverter.ConvertY(Math.Max(num34, minY));
                                }
                                else
                                {
                                    num41 = this.CoordConverter.ConvertY(num35);
                                    num42 = this.CoordConverter.ConvertY(num34);
                                }
                                if (flag4)
                                {
                                    num43 = base.SizeX * 20.0;
                                }
                                else
                                {
                                    num43 = Math.Abs((double)(this.CoordConverter.ConvertX(num4 / ((double)nsg)) - this.CoordConverter.ConvertX(0.0)));
                                }
                                double height = Math.Abs((double)(num42 - num41));
                                rc.Rect = new Rect(num28 - (0.5 * num43), Math.Min(num41, num42), num43, height);
                                sum[stackGroup, num26] = num22;
                            }
                            if (num33 >= 0.0)
                            {
                                (sum4 = sum2)[num63 = stackGroup, num64 = num26] = sum4[num63, num64] + num33;
                            }
                            else
                            {
                                (sum4 = sum3)[num63 = stackGroup, num64 = num26] = sum4[num63, num64] + num33;
                            }
                        }
                        else if (nullable != true)
                        {
                            double num46 = origin;
                            if (inverted)
                            {
                                double num47 = rc.GetMinX(this.CoordConverter.DataBounds2D);
                                double maxX = rc.GetMaxX(this.CoordConverter.DataBounds2D);
                                if (num46 < num47)
                                {
                                    num46 = num47;
                                }
                                else if (num46 > maxX)
                                {
                                    num46 = maxX;
                                }
                                double num49 = rc.ConvertX(num46);
                                double num50 = d;
                                double num51 = Math.Abs((double)(num49 - num28));
                                if (seriesOverlap != 0.0)
                                {
                                    double num52 = rc.ConvertY(y);
                                    double num53 = d * num5;
                                    if (seriesOverlap > 0.0)
                                    {
                                        num50 = num53 / ((num5 - (num5 * seriesOverlap)) + seriesOverlap);
                                    }
                                    else
                                    {
                                        num50 *= 1.0 + seriesOverlap;
                                    }
                                    double num54 = (num53 - num50) / ((double)(num5 - 1));
                                    rc.Rect = new Rect(Math.Min(num28, num49), (num52 - (0.5 * num53)) + (((num5 - num10) - 1) * num54), num51, num50);
                                }
                                else
                                {
                                    rc.Rect = new Rect(Math.Min(num28, num49), num29 - (0.5 * num50), num51, num50);
                                }
                            }
                            else
                            {
                                double num55 = rc.GetMinY(this.CoordConverter.DataBounds2D);
                                double maxY = rc.GetMaxY(this.CoordConverter.DataBounds2D);
                                if (num46 < num55)
                                {
                                    num46 = num55;
                                }
                                else if (num46 > maxY)
                                {
                                    num46 = maxY;
                                }
                                double num57 = rc.ConvertY(num46);
                                double num58 = d;
                                double num59 = Math.Abs((double)(num57 - num29));
                                if (seriesOverlap != 0.0)
                                {
                                    double num60 = rc.ConvertX(y);
                                    double num61 = d * num5;
                                    if (seriesOverlap > 0.0)
                                    {
                                        num58 = num61 / ((num5 - (num5 * seriesOverlap)) + seriesOverlap);
                                    }
                                    else
                                    {
                                        num58 *= 1.0 + seriesOverlap;
                                    }
                                    double num62 = (num61 - num58) / ((double)(num5 - 1));
                                    rc.Rect = new Rect((num60 - (0.5 * num61)) + (num10 * num62), Math.Min(num29, num57), num58, num59);
                                }
                                else
                                {
                                    rc.Rect = new Rect(num28 - (0.5 * num58), Math.Min(num29, num57), num58, num59);
                                }
                            }
                        }
                        rc.SetPoint(i, num28, num29);
                        if (pe != null)
                        {
                            Point point2 = new Point(num28, num29);
                            if ((pe is ICustomClipping) || clipBounds.Contains(point2))
                            {
                                if (double.IsNaN(naN))
                                {
                                    DataPoint dp = item.CreateDataPoint(si, i);
                                    base.RenderElement(objects, pe, item, rc, symbolShape, dp);
                                }
                                else if (((i == 0) || (Math.Abs((double)(point2.X - point.X)) > naN)) || ((Math.Abs((double)(point2.Y - point.Y)) > naN) || (i == (num16 - 1))))
                                {
                                    DataPoint point4 = item.CreateDataPoint(si, i);
                                    base.RenderElement(objects, pe, item, rc, symbolShape, point4);
                                    point = point2;
                                }
                            }
                        }
                    }
                    if (IsFastMode(renderMode))
                    {
                        this.RenderSeriesFast(rc, item, defel, objects);
                    }
                    else if ((renderMode != RenderMode.Default) && (IsLine(new ChartType?(base.ChartType)) || IsLine(item.ChartType)))
                    {
                        this.RenderLinesFast(rc, item, si, objects);
                    }
                    else
                    {
                        PlotElement element3 = base.RenderConnection(item, rc, si);
                        if (element3 != null)
                        {
                            item.Children.Insert(0, element3);
                        }
                    }
                    if (isClustered)
                    {
                        if (rc.ClusterPlotAreaIndex == 0)
                        {
                            num10++;
                        }
                        else
                        {
                            numArray2[rc.ClusterPlotAreaIndex]++;
                        }
                    }
                }
                si++;
            }
            return objects.ToArray();
        }

        Rect IView2DRenderer.Measure(Size sz)
        {
            base.AnalyzeData(base.IsStacked);
            Rect rect = new Rect();
            double num = (this.NClustered(Utils.GetIsClustered(false, base.Symbol)).Sum() > 0) ? ((0.5 * this.GetClusterWidth()) * this._dataInfo.DeltaX) : 0.0;
            double num2 = 0.0;
            if (num == 0.0)
            {
                num2 = Math.Max(this.GetMaxSymbolWidth(), this._dataInfo.SymbolSize.Width);
            }
            double height = this._dataInfo.SymbolSize.Height;
            if ((this._dataInfo.nser > 0) && (this._dataInfo.npts > 0))
            {
                double minY;
                double maxY;
                if (this._dataInfo.ndim >= 2)
                {
                    rect.X = this._dataInfo.MinX;
                    rect.Width = this._dataInfo.MaxX - this._dataInfo.MinX;
                }
                else
                {
                    rect.X = 0.0;
                    rect.Width = this._dataInfo.npts - 1;
                }
                double num4 = base.Inverted ? sz.Height : sz.Width;
                if ((num2 > 0.0) && (num2 < num4))
                {
                    double num5 = (num4 / (num4 - num2)) - 1.0;
                    num = (num5 * rect.Width) * 0.6;
                }
                rect.X -= num;
                rect.Width += 2.0 * num;
                if (rect.Width == 0.0)
                {
                    rect.X -= 0.5;
                    rect.Width = 1.0;
                }
                if (base.IsStacked)
                {
                    if (base.IsStacked100)
                    {
                        minY = this._dataInfo.MinVals[0] * 100.0;
                        maxY = this._dataInfo.MaxVals[0] * 100.0;
                        if (minY == maxY)
                        {
                            minY = 0.0;
                            maxY = 100.0;
                        }
                    }
                    else
                    {
                        minY = this._dataInfo.MinVals[0];
                        maxY = this._dataInfo.MaxVals[0];
                        if (maxY < 0.0)
                        {
                            maxY = 0.0;
                        }
                        if (minY > 0.0)
                        {
                            minY = 0.0;
                        }
                    }
                }
                else
                {
                    minY = this._dataInfo.MinY;
                    maxY = this._dataInfo.MaxY;
                    if ((base.ChartType == ChartType.Column) || (base.ChartType == ChartType.Bar))
                    {
                        Chart visual = ((IRenderer)this).Visual as Chart;
                        if (visual != null)
                        {
                            double origin = BarColumnOptions.GetOrigin(visual);
                            if (((minY > origin) && (visual.View != null)) && (visual.View.AxisY != null))
                            {
                                if (double.IsNaN(visual.View.AxisY.LogBase))
                                {
                                    minY = origin;
                                }
                                else if (origin > 0.0)
                                {
                                    minY = origin;
                                }
                            }
                        }
                    }
                }
                if (minY == maxY)
                {
                    double num9 = (minY == 0.0) ? 0.5 : Math.Abs((double)(minY * 0.1));
                    minY -= num9;
                    maxY += num9;
                }
                rect.Y = minY;
                rect.Height = maxY - minY;
                double num10 = 0.0;
                double num11 = base.Inverted ? sz.Width : sz.Height;
                if ((height > 0.0) && (height < num11))
                {
                    double num12 = (num11 / (num11 - height)) - 1.0;
                    num10 = (num12 * rect.Height) * 0.6;
                }
                rect.Y -= num10;
                rect.Height += 2.0 * num10;
            }
            this._rect = base.Inverted ? new Rect(rect.Y, rect.X, rect.Height, rect.Width) : rect;
            return this._rect;
        }

        private double GetMaxSymbolWidth()
        {
            double num = 0.0;
            foreach (DataSeries series in base.Series)
            {
                if (series is IMeasureSymbolWidth)
                {
                    DataTemplate symbol = series.Symbol as DataTemplate;
                    if (symbol == null)
                    {
                        symbol = base.Symbol as DataTemplate;
                    }
                    if (symbol != null)
                    {
                        PlotElement element = symbol.LoadContent() as PlotElement;
                        if (element != null)
                        {
                            num = Math.Max(num, element.Size.Width);
                        }
                    }
                    else if (base.Symbol is PlotElement)
                    {
                        num = Math.Max(num, ((PlotElement)base.Symbol).Size.Width);
                    }
                }
            }
            return num;
        }

        private static bool IsFastMode(RenderMode rmode)
        {
            return (rmode == RenderMode.Bitmap);
        }

        internal static bool IsLine(ChartType? ct)
        {
            return (ct.HasValue && ct.ToString().StartsWith("Line"));
        }

        internal override bool IsValidAuxAxis(string axname)
        {
            if (this.ValidAuxAxes != null)
            {
                for (int i = 0; i < this.ValidAuxAxes.Length; i++)
                {
                    if (this.ValidAuxAxes[i] == axname)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private void RenderLinesFast(RenderContext rc, DataSeries ds, int i, List<UIElement> objs)
        {
        }

        private void RenderSeriesFast(RenderContext rc, DataSeries ds, IPlotElement defel, List<UIElement> objs)
        {
            Rect plotRect = base.Chart.View.PlotRect;
            int width = (int)plotRect.Width;
            int height = (int)plotRect.Height;
            if (ds.Bitmap == null)
            {
                ds.Bitmap = new WriteableBitmap(width, height);
            }
            else if ((ds.Bitmap.PixelWidth != width) || (ds.Bitmap.PixelHeight != height))
            {
                ds.Bitmap = new WriteableBitmap(width, height);
            }
            else
            {
                ds.Bitmap.Clear();
            }
            WriteableBitmap bmp = ds.Bitmap;
            Point[] points = rc.Points;
            if (points != null)
            {
                int length = points.Length;
                if ((length > 1) && (IsLine(new ChartType?(base.ChartType)) || IsLine(ds.ChartType)))
                {
                    if (ds.ConnectionShape == null)
                    {
                        ds.ConnectionShape = base.StyleGen.Next();
                    }
                    ShapeStyle connectionShape = ds.ConnectionShape;
                    SolidColorBrush brush = ((ds.ReadLocalValue(DataSeries.ConnectionStrokeProperty) != DependencyProperty.UnsetValue) ? ((SolidColorBrush)ds.ConnectionStroke) : ((SolidColorBrush)connectionShape.Fill)) as SolidColorBrush;
                    if (ds.ReadLocalValue(DataSeries.ConnectionStrokeThicknessProperty) != DependencyProperty.UnsetValue)
                    {
                        double connectionStrokeThickness = ds.ConnectionStrokeThickness;
                    }
                    DoubleCollection connectionStrokeDashes = ds.ConnectionStrokeDashes;
                    int[] numArray = new int[points.Length * 2];
                    for (int i = 0; i < points.Length; i++)
                    {
                        numArray[2 * i] = (int)Math.Round((double)(points[i].X - plotRect.X));
                        numArray[(2 * i) + 1] = (int)Math.Round((double)(points[i].Y - plotRect.Y));
                    }
                    if (brush != null)
                    {
                        bmp.DrawPolyline(numArray, brush.Color);
                    }
                }
                IPlotElement element = defel;
                ShapeStyle symbolShape = ds.SymbolShape;
                Brush fill = null;
                Brush brush3 = null;
                Size symbolSize = new Size(10.0, 10.0);
                double num5 = 0.0;
                double num6 = 0.0;
                if (ds.ChartType.HasValue)
                {
                    ChartSubtype subtype = ChartTypes.GetSubtype(ds.ChartType.ToString());
                    if (subtype != null)
                    {
                        element = base.CreateElement(subtype.Symbol, null);
                    }
                }
                if (((element is Symbol) || (element is DotSymbol)) || (ds.SymbolMarker != Marker.None))
                {
                    if (ds.ReadLocalValue(DataSeries.SymbolFillProperty) == DependencyProperty.UnsetValue)
                    {
                        fill = symbolShape.Fill;
                    }
                    else
                    {
                        fill = ds.SymbolFill;
                    }
                    Brush stroke = null;
                    if (ds.ReadLocalValue(DataSeries.SymbolStrokeProperty) == DependencyProperty.UnsetValue)
                    {
                        stroke = symbolShape.Stroke;
                    }
                    else
                    {
                        stroke = ds.SymbolStroke;
                    }
                    if (ds.ReadLocalValue(DataSeries.SymbolStrokeThicknessProperty) != DependencyProperty.UnsetValue)
                    {
                        double symbolStrokeThickness = ds.SymbolStrokeThickness;
                    }
                    if (stroke != null)
                    {
                        brush3 = stroke;
                    }
                    if ((ds.ReadLocalValue(DataSeries.SymbolSizeProperty) != DependencyProperty.UnsetValue) && !ds.SymbolSize.IsEmpty)
                    {
                        symbolSize = ds.SymbolSize;
                    }
                    num5 = 0.5 * symbolSize.Width;
                    num6 = 0.5 * symbolSize.Height;
                    SolidColorBrush brush5 = brush3 as SolidColorBrush;
                    SolidColorBrush brush6 = fill as SolidColorBrush;
                    if ((brush5 != null) || (brush6 != null))
                    {
                        for (int j = 0; j < length; j++)
                        {
                            Point point = points[j];
                            point.X -= plotRect.X;
                            point.Y -= plotRect.Y;
                            if ((ds.SymbolMarker == Marker.None) || (ds.SymbolMarker == Marker.Dot))
                            {
                                if (brush6 != null)
                                {
                                    bmp.FillEllipseCentered((int)point.X, (int)point.Y, (int)num5, (int)num6, brush6.Color);
                                }
                                if (brush5 != null)
                                {
                                    bmp.DrawEllipseCentered((int)point.X, (int)point.Y, (int)num5, (int)num6, brush5.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.Box)
                            {
                                if (brush6 != null)
                                {
                                    bmp.FillRectangle((int)(point.X - num5), (int)(point.Y - num6), (int)(point.X + num5), (int)(point.Y + num6), brush6.Color);
                                }
                                if (brush5 != null)
                                {
                                    bmp.DrawRectangle((int)(point.X - num5), (int)(point.Y - num6), (int)(point.X + num5), (int)(point.Y + num6), brush5.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.Diamond)
                            {
                                if (brush6 != null)
                                {
                                    bmp.FillQuad((int)(point.X - num5), (int)point.Y, (int)point.X, (int)(point.Y - num6), (int)(point.X + num5), (int)point.Y, (int)point.X, (int)(point.Y + num6), brush5.Color);
                                }
                                if (brush5 != null)
                                {
                                    bmp.DrawQuad((int)(point.X - num5), (int)point.Y, (int)point.X, (int)(point.Y - num6), (int)(point.X + num5), (int)point.Y, (int)point.X, (int)(point.Y + num6), brush5.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.Triangle)
                            {
                                double num8 = num5 * cosPi6;
                                double num9 = num6 * sinPi6;
                                if (brush6 != null)
                                {
                                    bmp.FillTriangle((int)point.X, (int)(point.Y - num6), (int)(point.X + num8), (int)(point.Y + num9), (int)(point.X - num8), (int)(point.Y + num9), brush6.Color);
                                }
                                if (brush5 != null)
                                {
                                    bmp.DrawTriangle((int)point.X, (int)(point.Y - num6), (int)(point.X + num8), (int)(point.Y + num9), (int)(point.X - num8), (int)(point.Y + num9), brush5.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.Cross)
                            {
                                if (brush6 != null)
                                {
                                    bmp.DrawLine((int)point.X, (int)(point.Y - num6), (int)point.X, (int)(point.Y + num6), brush6.Color);
                                    bmp.DrawLine((int)(point.X - num5), (int)point.Y, (int)(point.X + num5), (int)point.Y, brush6.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.DiagonalCross)
                            {
                                if (brush6 != null)
                                {
                                    bmp.DrawLine((int)(point.X - num5), (int)(point.Y - num6), (int)(point.X + num5), (int)(point.Y + num6), brush6.Color);
                                    bmp.DrawLine((int)(point.X - num5), (int)(point.Y + num5), (int)(point.X + num5), (int)(point.Y - num6), brush6.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.Star4)
                            {
                                int[] numArray2 = new int[0x12];
                                int num10 = (int)(0.3 * num5);
                                int num11 = (int)(0.3 * num6);
                                int x = (int)point.X;
                                int y = (int)point.Y;
                                numArray2[0] = x;
                                numArray2[1] = y - ((int)num6);
                                numArray2[2] = x + num10;
                                numArray2[3] = y - num11;
                                numArray2[4] = x + ((int)num5);
                                numArray2[5] = y;
                                numArray2[6] = x + num10;
                                numArray2[7] = y + num11;
                                numArray2[8] = x;
                                numArray2[9] = y + ((int)num6);
                                numArray2[10] = x - num10;
                                numArray2[11] = y + num11;
                                numArray2[12] = x - ((int)num5);
                                numArray2[13] = y;
                                numArray2[14] = x - num10;
                                numArray2[15] = y - num11;
                                numArray2[0x10] = numArray2[0];
                                numArray2[0x11] = numArray2[1];
                                if (brush6 != null)
                                {
                                    bmp.FillPolygon(numArray2, brush6.Color);
                                }
                                if (brush5 != null)
                                {
                                    bmp.DrawPolyline(numArray2, brush5.Color);
                                }
                            }
                            else if (ds.SymbolMarker == Marker.Star8)
                            {
                                int[] numArray3 = new int[0x22];
                                int num14 = (int)(point.X + 0.5);
                                int num15 = (int)(point.Y + 0.5);
                                int num16 = (int)(num5 / Math.Sqrt(2.0));
                                int num17 = (int)(num6 / Math.Sqrt(2.0));
                                int num18 = (int)((0.4 * num6) * Math.Sin(0.39269908169872414));
                                int num19 = (int)((0.4 * num5) * Math.Cos(0.39269908169872414));
                                numArray3[0] = num14;
                                numArray3[1] = num15 - ((int)num6);
                                numArray3[2] = num14 + num18;
                                numArray3[3] = num15 - num19;
                                numArray3[4] = num14 + num16;
                                numArray3[5] = num15 - num17;
                                numArray3[6] = num14 + num19;
                                numArray3[7] = num15 - num18;
                                numArray3[8] = num14 + ((int)num5);
                                numArray3[9] = num15;
                                numArray3[10] = num14 + num19;
                                numArray3[11] = num15 + num18;
                                numArray3[12] = num14 + num16;
                                numArray3[13] = num15 + num17;
                                numArray3[14] = num14 + num18;
                                numArray3[15] = num15 + num19;
                                numArray3[0x10] = num14;
                                numArray3[0x11] = num15 + ((int)num6);
                                numArray3[0x12] = num14 - num18;
                                numArray3[0x13] = num15 + num19;
                                numArray3[20] = num14 - num16;
                                numArray3[0x15] = num15 + num17;
                                numArray3[0x16] = num14 - num19;
                                numArray3[0x17] = num15 + num18;
                                numArray3[0x18] = num14 - ((int)num5);
                                numArray3[0x19] = num15;
                                numArray3[0x1a] = num14 - num19;
                                numArray3[0x1b] = num15 - num18;
                                numArray3[0x1c] = num14 - num16;
                                numArray3[0x1d] = num15 - num17;
                                numArray3[30] = num14 - num18;
                                numArray3[0x1f] = num15 - num19;
                                numArray3[0x20] = numArray3[0];
                                numArray3[0x21] = numArray3[1];
                                if (brush6 != null)
                                {
                                    bmp.FillPolygon(numArray3, brush6.Color);
                                }
                                if (brush5 != null)
                                {
                                    bmp.DrawPolyline(numArray3, brush5.Color);
                                }
                            }
                        }
                    }
                }
                Image image = new Image
                {
                    Source = bmp
                };
                Canvas.SetLeft(image, plotRect.X);
                Canvas.SetTop(image, plotRect.Y);
                objs.Add(image);
            }
        }

        // Properties
        internal override AxisView AxisView
        {
            get
            {
                return AxisView.Cartseian;
            }
        }

        AxisStyle IView2DRenderer.Axis
        {
            get
            {
                return AxisStyle.Cartesian;
            }
        }
    }
}
